import { ref, watch, Ref, defineComponent, computed } from 'vue';
import {
  getDataPickerProps,
  getEditorEmits,
  useNamespace,
} from '@ibiz-template/vue3-util';
import './ibiz-mpicker.scss';
import { PickerEditorController } from '../picker-editor.controller';

export const IBizMPicker = defineComponent({
  name: 'IBizMPicker',
  props: getDataPickerProps<PickerEditorController>(),
  emits: getEditorEmits(),
  setup(props, { emit }) {
    const ns = useNamespace('mpicker');

    const c = props.controller!;

    // 当前表单项绑定值key的集合
    const curValue: Ref<Array<string>> = ref([]);

    // 实体数据集
    const items: Ref<IData[]> = ref([]);

    // 选中项key-value键值对
    const selectItems: Ref<IData[]> = ref([]);

    // 下拉是否打开
    const open = ref(false);

    // 加载中
    const loading: Ref<boolean> = ref(false);

    // 监听传入值
    watch(
      () => props.value,
      newVal => {
        curValue.value = [];
        selectItems.value = [];
        if (newVal) {
          selectItems.value = JSON.parse(newVal);
          selectItems.value.forEach((item: IData) => {
            curValue.value.push(item.srfkey);

            // 选项没有的时候补充选项
            const index = items.value.findIndex(i =>
              Object.is(i.srfkey, item.srfkey),
            );
            if (index < 0) {
              items.value.push({
                srfkey: item.srfkey,
                srfmajortext: item.srfmajortext,
              });
            }
          });
        }
      },
      { immediate: true, deep: true },
    );

    // 处理视图关闭，往外抛值
    const handleOpenViewClose = (result: IData[]) => {
      // 抛出值集合
      const valArr: IData[] = [];
      if (result && Array.isArray(result)) {
        result.forEach((select: IData) => {
          // 回显并且回来的选中值只有srfkey和srfmajortext,所以||
          const formattedItem = {
            srfkey: select[c.keyName] || select.srfkey,
            srfmajortext: select[c.textName] || select.srfmajortext,
          };
          valArr.push(formattedItem);

          // 选项不存在的补充到选项里
          const index = items.value.findIndex(item =>
            Object.is(item[c.keyName], select[c.keyName]),
          );
          if (index < 0) {
            items.value.push(formattedItem);
          }
        });
      }
      const value = valArr.length > 0 ? JSON.stringify(valArr) : '';
      emit('change', value);
    };

    // 打开数据选择视图
    const openPickUpView = async () => {
      let selectedData;
      if (selectItems.value.length) {
        selectedData = JSON.stringify(selectItems.value);
      }
      const res = await c.openPickUpView(props.data!, selectedData);
      if (res) {
        handleOpenViewClose(res);
      }
    };

    // 下拉选中回调
    const onSelect = (selects: string[]) => {
      const valArr: Array<IData> = [];
      if (selects.length > 0) {
        selects.forEach((select: string) => {
          const findItem = items.value.find(item =>
            Object.is(item.srfkey, select),
          );
          if (findItem) {
            valArr.push({
              srfkey: findItem.srfkey,
              srfmajortext: findItem.srfmajortext,
            });
          }
        });
        const value = valArr.length > 0 ? JSON.stringify(valArr) : '';
        emit('change', value);
      } else {
        emit('change', '');
      }
    };

    // 搜索
    const onSearch = async (query: string) => {
      if (c.model.appDataEntityId) {
        loading.value = true;
        try {
          const trimQuery = query.trim();
          const res = await c.getServiceData(trimQuery, props.data!);
          loading.value = false;
          if (res) {
            items.value = res.data.map(item => ({
              srfkey: item[c.keyName],
              srfmajortext: item[c.textName],
            }));
          }
        } catch (error) {
          loading.value = false;
        }
      }
    };

    // 下拉打开
    const onOpenChange = (flag: boolean) => {
      open.value = flag;
      if (open.value) {
        items.value = [];
        onSearch('');
      }
    };

    // 信息展示，只显示名称。
    const valueText = computed(() => {
      return selectItems.value
        .map(item => {
          return item.srfmajortext;
        })
        .join(',');
    });

    // 聚焦
    const onFocus = () => {
      emit('focus');
    };

    // 失焦
    const onBlur = () => {
      emit('blur');
    };

    return {
      ns,
      c,
      curValue,
      loading,
      items,
      valueText,
      onSearch,
      onOpenChange,
      onSelect,
      openPickUpView,
      onFocus,
      onBlur,
    };
  },
  render() {
    return (
      <div
        class={[
          this.ns.b(),
          this.disabled ? this.ns.m('disabled') : '',
          this.readonly ? this.ns.m('readonly') : '',
        ]}
        ref='editorRef'
      >
        {this.readonly && this.valueText}
        {!this.readonly && (
          <el-select
            v-model={this.curValue}
            filterable
            remote
            multiple
            loading={this.loading}
            placeholder={this.c.placeHolder ? this.c.placeHolder : ' '}
            remote-method={this.onSearch}
            onVisibleChange={this.onOpenChange}
            onChange={this.onSelect}
            disabled={this.disabled}
            onFocus={this.onFocus}
            onBlur={this.onBlur}
          >
            {this.items.map((item, index) => {
              return (
                <el-option
                  key={index}
                  value={item.srfkey}
                  label={item.srfmajortext}
                ></el-option>
              );
            })}
          </el-select>
        )}
        {!this.readonly && (
          <div class={this.ns.e('buns-position')}>
            <div class={this.ns.e('btns')}>
              {this.c.model.pickupAppViewId ? (
                <ion-icon
                  onClick={this.openPickUpView}
                  name='search'
                ></ion-icon>
              ) : null}
            </div>
          </div>
        )}
      </div>
    );
  },
});
